package com.gitee.wsl.doc.json

import arrow.optics.Optional
import arrow.optics.Traversal
import com.gitee.wsl.doc.json.selects.JsonPath
import com.gitee.wsl.doc.json.selects.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlin.test.Test

class JsonPathTest {
    private val JSON_STRING = """
    {
      "name": "Arrow",
      "address": {
        "city": "Functional Town",
        "street": {
          "number": 1337,
          "name": "Functional street"
        }
      },
      "employees": [
        {
          "name": "John",
          "lastName": "doe"
        },
        {
          "name": "Jane",
          "lastName": "doe"
        }
      ]
    }"""

    @Test
    fun testPathEvery(){
        val json: JsonElement = Json.decodeFromString(JSON_STRING)
        val employeesName: Traversal<JsonElement, String> = JsonPath.pathEvery("employees.*.name").string
        val res: JsonElement = employeesName.modify(json, String::uppercase).also(::println)
        employeesName.getAll(res).also(::println)
    }

    @Test
    fun testPathSelect(){
        val json: JsonElement = Json.decodeFromString(JSON_STRING)
        val employeesName: Traversal<JsonElement, String> = JsonPath.select("employees").every.select("name").string
        val res: JsonElement = employeesName.modify(json, String::uppercase).also(::println)
        employeesName.getAll(res).also(::println)
    }

    @Test
    fun testPath(){
        val json: JsonElement = Json.decodeFromString(JSON_STRING)
        val name: Optional<JsonElement, String> = JsonPath.path("address.street.name").string
        val res: JsonElement = name.modify(json, String::uppercase).also(::println)
        name.getOrNull(res)?.also(::println)
    }
}